WebGL์ ๋ค๋จ๊ณ ์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ์ฌ์ธต ๋ถ์ํฉ๋๋ค. GLSL, ๋ฒํ ์ค/ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋, ๋งํน, ๊ทธ๋ฆฌ๊ณ ๊ธ๋ก๋ฒ 3D ๊ทธ๋ํฝ ๊ฐ๋ฐ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.
WebGL ์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ: ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์๋ฅผ ์ํ ๋ค๋จ๊ณ ์ฒ๋ฆฌ์ ์ดํด
ํ๊ธฐ์ฐจ๊ณ ๋์์์ด ์งํํ๋ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ WebGL์ ๋ธ๋ผ์ฐ์ ๋ด์์ ๊ณ ์ฑ๋ฅ ๋ํํ 3D ๊ทธ๋ํฝ์ ์ง์ ์ ๊ณตํ๋ ๋ฐ ์ด์์ด ๋ฉ๋๋ค. ๋ชฐ์ ํ ๋ฐ์ดํฐ ์๊ฐํ๋ถํฐ ๋งคํน์ ์ธ ๊ฒ์ ๋ฐ ๋ณต์กํ ์๋ฎฌ๋ ์ด์ ์ ์ด๋ฅด๊ธฐ๊น์ง, WebGL์ ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ด ํ๋ฌ๊ทธ์ธ ์์ด๋ ๋ฉ์ง ์๊ฐ์ ๊ฒฝํ์ ๋ง๋ค ์ ์๋๋ก ์ง์ํฉ๋๋ค. WebGL์ ๋ ๋๋ง ๊ธฐ๋ฅ์ ํต์ฌ์๋ ์ค์ํ ๊ตฌ์ฑ ์์์ธ ์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ด ์์ต๋๋ค. ์ด ๋ณต์กํ ๋ค๋จ๊ณ ํ๋ก์ธ์ค๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ ฐ์ด๋ฉ ์ธ์ด ์ฝ๋๋ฅผ ๊ทธ๋ํฝ ์ฒ๋ฆฌ ์ฅ์น(GPU)์์ ์ง์ ์คํ๋๋ ๊ณ ๋๋ก ์ต์ ํ๋ ๋ช ๋ น์ผ๋ก ๋ณํํฉ๋๋ค.
WebGL์ ๋ง์คํฐํ๋ ค๋ ๋ชจ๋ ๊ฐ๋ฐ์์๊ฒ ์ด ํ์ดํ๋ผ์ธ์ ์ดํดํ๋ ๊ฒ์ ๋จ์ํ ํ๋ฌธ์ ์ฐ์ต์ด ์๋๋๋ค. ํจ์จ์ ์ด๊ณ ์ค๋ฅ ์๋ ๊ณ ์ฑ๋ฅ ์ ฐ์ด๋๋ฅผ ์์ฑํ๋ ๋ฐ ํ์์ ์ ๋๋ค. ์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ WebGL ์ ฐ์ด๋ ์ปดํ์ผ ๋ฐ ๋งํน ํ๋ก์ธ์ค์ ๊ฐ ๋จ๊ณ๋ฅผ ์์ธํ ์๋ดํ๋ฉฐ, ๋ค๋จ๊ณ ์ํคํ ์ฒ์ '์ด์ '๋ฅผ ํ์ํ๊ณ ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ ๊ฐ๋ ฅํ 3D ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ง์์ ์ ๊ณตํฉ๋๋ค.
์ ฐ์ด๋์ ๋ณธ์ง: ์ค์๊ฐ ๊ทธ๋ํฝ์ค์ ๋๋ ฅ
์ปดํ์ผ ์ธ๋ถ ์ฌํญ์ ๋ฐ์ด๋ค๊ธฐ ์ ์, ์ ฐ์ด๋๊ฐ ๋ฌด์์ด๋ฉฐ ํ๋ ์ค์๊ฐ ๊ทธ๋ํฝ์์ ์ ํ์์ ์ธ์ง ๊ฐ๋ตํ๊ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ ฐ์ด๋๋ GLSL(OpenGL Shading Language)์ด๋ผ๋ ํน์ ์ธ์ด๋ก ์์ฑ๋ GPU์์ ์คํ๋๋ ์์ ํ๋ก๊ทธ๋จ์ ๋๋ค. ์ ํต์ ์ธ CPU ํ๋ก๊ทธ๋จ๊ณผ ๋ฌ๋ฆฌ ์ ฐ์ด๋๋ ์์ฒ ๊ฐ์ ์ฒ๋ฆฌ ์ฅ์น์์ ๋ณ๋ ฌ๋ก ์คํ๋์ด ํ๋ฉด์ ๋ชจ๋ ํฝ์ ์ ๋ํ ์์ ๊ณ์ฐ์ด๋ ์๋ฐฑ๋ง ๊ฐ์ ์ ์ ์์น ๋ณํ๊ณผ ๊ฐ์ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ์์ ์ ์์ฒญ๋๊ฒ ํจ์จ์ ์ ๋๋ค.
WebGL์์ ์ฌ๋ฌ๋ถ์ด ์ง์์ ์ผ๋ก ์ํธ ์์ฉํ๊ฒ ๋ ๋ ๊ฐ์ง ์ฃผ์ ์ ฐ์ด๋ ์ ํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ฒํ ์ค ์ ฐ์ด๋(Vertex Shaders): ์ด ์ ฐ์ด๋๋ 3D ๋ชจ๋ธ์ ๊ฐ๋ณ ์ ์ (์ )์ ์ฒ๋ฆฌํฉ๋๋ค. ์ฃผ์ ์ญํ ์ ์ ์ ์์น๋ฅผ ๋ก์ปฌ ๋ชจ๋ธ ๊ณต๊ฐ์์ ํด๋ฆฝ ๊ณต๊ฐ(์นด๋ฉ๋ผ์ ๋ณด์ด๋ ๊ณต๊ฐ)์ผ๋ก ๋ณํํ๊ณ , ์์, ํ ์ค์ฒ ์ขํ ๋๋ ๋ ธ๋ฉ๊ณผ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌํ๋ฉฐ, ๋ชจ๋ ์ ์ ๋ณ ๊ณ์ฐ์ ์ํํ๋ ๊ฒ์ ๋๋ค.
- ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋(Fragment Shaders): ํฝ์ ์ ฐ์ด๋๋ก๋ ์๋ ค์ง ์ด ํ๋ก๊ทธ๋จ์ ํ๋ฉด์ ๋ํ๋ ๊ฐ ํฝ์ (๋๋ ํ๋๊ทธ๋จผํธ)์ ์ต์ข ์์์ ๊ฒฐ์ ํฉ๋๋ค. ๋ฒํ ์ค ์ ฐ์ด๋์์ ๋ณด๊ฐ๋ ๋ฐ์ดํฐ(๋ณด๊ฐ๋ ํ ์ค์ฒ ์ขํ ๋๋ ๋ ธ๋ฉ ๋ฑ)๋ฅผ ๊ฐ์ ธ์ ํ ์ค์ฒ๋ฅผ ์ํ๋งํ๊ณ , ์กฐ๋ช ๊ณ์ฐ์ ์ ์ฉํ๋ฉฐ, ์ต์ข ์์์ ์ถ๋ ฅํฉ๋๋ค.
์ ฐ์ด๋์ ๊ฐ๋ ฅํจ์ ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ฅ์ฑ์ ์์ต๋๋ค. ๊ณ ์ ๊ธฐ๋ฅ ํ์ดํ๋ผ์ธ(GPU๊ฐ ๋ฏธ๋ฆฌ ์ ์๋ ์ผ๋ จ์ ์์ ์ ์ํํ๋ ๊ณณ) ๋์ , ์ ฐ์ด๋๋ ๊ฐ๋ฐ์๊ฐ ์ฌ์ฉ์ ์ง์ ๋ ๋๋ง ๋ก์ง์ ์ ์ํ ์ ์๋๋ก ํ์ฌ ์ต์ข ๋ ๋๋ง๋ ์ด๋ฏธ์ง์ ๋ํ ํ์ํ ์์ ์ ๋ฐ ๊ธฐ์ ์ ์ ์ด๊ถ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ์ ์ฐ์ฑ์ ๊ฒฌ๊ณ ํ ์ปดํ์ผ ์์คํ ์ ํ์์ฑ์ ๋๋ฐํฉ๋๋ค. ์ด๋ฌํ ์ฌ์ฉ์ ์ง์ ํ๋ก๊ทธ๋จ์ GPU๊ฐ ์ดํดํ๊ณ ํจ์จ์ ์ผ๋ก ์คํํ ์ ์๋ ๋ช ๋ น์ผ๋ก ๋ฒ์ญ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
WebGL ๊ทธ๋ํฝ์ค ํ์ดํ๋ผ์ธ ๊ฐ์
์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ์์ ํ ์ดํดํ๋ ค๋ฉด ๋ ๋์ WebGL ๊ทธ๋ํฝ์ค ํ์ดํ๋ผ์ธ ๋ด์์ ๊ทธ ์์น๋ฅผ ์ดํดํ๋ ๊ฒ์ด ๋์์ด ๋ฉ๋๋ค. ์ด ํ์ดํ๋ผ์ธ์ ๊ธฐํํ์ ๋ฐ์ดํฐ๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฒ์ ์ ์๋ ์์ ๋ถํฐ ํ๋ฉด์ ํฝ์ ๋ก ์ต์ข ํ์๋ ๋๊น์ง์ ์ ์ฒด ๊ณผ์ ์ ์ค๋ช ํฉ๋๋ค. ๊ฐ์ํ๋์์ง๋ง, ์ฃผ์ ๋จ๊ณ๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ ํ๋ฆฌ์ผ์ด์ ๋จ๊ณ (CPU): JavaScript ์ฝ๋๋ ๋ฐ์ดํฐ(์ ์ ๋ฒํผ, ํ ์ค์ฒ, ์ ๋ํผ)๋ฅผ ์ค๋นํ๊ณ , ์นด๋ฉ๋ผ ๋งค๊ฐ๋ณ์๋ฅผ ์ค์ ํ๋ฉฐ, ๋๋ก์ฐ ํธ์ถ์ ๋ฐํํฉ๋๋ค.
- ์ ์ ์ ฐ์ด๋ฉ (GPU): ๋ฒํ ์ค ์ ฐ์ด๋๋ ๊ฐ ์ ์ ์ ์ฒ๋ฆฌํ์ฌ ์์น๋ฅผ ๋ณํํ๊ณ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌํฉ๋๋ค.
- ํ๋ฆฌ๋ฏธํฐ๋ธ ์ด์ ๋ธ๋ฆฌ (GPU): ์ ์ ๋ค์ด ํ๋ฆฌ๋ฏธํฐ๋ธ(์ , ์ , ์ผ๊ฐํ)๋ก ๊ทธ๋ฃนํ๋ฉ๋๋ค.
- ๋์คํฐํ (GPU): ํ๋ฆฌ๋ฏธํฐ๋ธ๋ ํ๋๊ทธ๋จผํธ๋ก ๋ณํ๋๊ณ , ํ๋๊ทธ๋จผํธ๋ณ ์์ฑ(์์ ๋๋ ํ ์ค์ฒ ์ขํ ๋ฑ)์ด ๋ณด๊ฐ๋ฉ๋๋ค.
- ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋ฉ (GPU): ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๋ ๊ฐ ํ๋๊ทธ๋จผํธ์ ์ต์ข ์์์ ๊ณ์ฐํฉ๋๋ค.
- ํ๋๊ทธ๋จผํธ๋ณ ์ฐ์ฐ (GPU): ํ๋๊ทธ๋จผํธ๊ฐ ํ๋ ์๋ฒํผ์ ๊ธฐ๋ก๋๊ธฐ ์ ์ ๊น์ด ํ ์คํธ, ๋ธ๋ ๋ฉ ๋ฐ ์คํ ์ค ํ ์คํธ๊ฐ ์ํ๋ฉ๋๋ค.
์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฒํ ์ค ์ ฐ์ด๋์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋(2๋จ๊ณ ๋ฐ 5๋จ๊ณ)๋ฅผ GPU์์ ์คํํ ์ ์๋๋ก ์ค๋นํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ์ฌ๋์ด ์์ฑํ GLSL ์ฝ๋์ ์๊ฐ์ ์ถ๋ ฅ์ ๊ตฌ๋ํ๋ ์ ์์ค ๋จธ์ ๋ช ๋ น ์ฌ์ด์ ์ค์ํ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ์ ๋๋ค.
WebGL ์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ: ๋ค๋จ๊ณ ์ฒ๋ฆฌ ์ฌ์ธต ๋ถ์
WebGL ์ ฐ์ด๋ ์ฒ๋ฆฌ ๋งฅ๋ฝ์์ "๋ค๋จ๊ณ(multi-stage)"๋ผ๋ ์ฉ์ด๋ ์์ GLSL ์์ค ์ฝ๋๋ฅผ GPU์์ ์คํํ ์ ์๋๋ก ์ค๋นํ๋ ๋ฐ ๊ด๋ จ๋ ๊ณ ์ ํ๊ณ ์์ฐจ์ ์ธ ๋จ๊ณ๋ฅผ ๋ํ๋ ๋๋ค. ์ด๋ ๋จ์ผ์ ๊ฑฐ๋ํ ์์ ์ด ์๋๋ผ ๋ชจ๋์ฑ, ์ค๋ฅ ๊ฒฉ๋ฆฌ ๋ฐ ์ต์ ํ ๊ธฐํ๋ฅผ ์ ๊ณตํ๋ ์ ์คํ๊ฒ ์กฐ์ ๋ ์์์ ๋๋ค. ๊ฐ ๋จ๊ณ๋ฅผ ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1๋จ๊ณ: ์ ฐ์ด๋ ์์ฑ ๋ฐ ์์ค ์ ๊ณต
WebGL์์ ์ ฐ์ด๋ ์์ ์ ์์ํ๋ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ์ ฐ์ด๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์์ค ์ฝ๋๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋ ๊ฐ์ง ํต์ฌ WebGL API ํธ์ถ์ ํตํด ์ํ๋ฉ๋๋ค:
gl.createShader(type)
- ์ด ํจ์๋ ๋น ์
ฐ์ด๋ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์์ฑํ๋ ค๋ ์
ฐ์ด๋์
type์ ์ง์ ํด์ผ ํฉ๋๋ค:gl.VERTEX_SHADER๋๋gl.FRAGMENT_SHADER. - ๋ด๋ถ์ ์ผ๋ก WebGL ์ปจํ ์คํธ๋ GPU ๋๋ผ์ด๋ฒ ์ธก์์ ์ด ์ ฐ์ด๋ ๊ฐ์ฒด์ ๋ํ ๋ฆฌ์์ค๋ฅผ ํ ๋นํฉ๋๋ค. ์ด๋ JavaScript ์ฝ๋๊ฐ ์ ฐ์ด๋๋ฅผ ์ฐธ์กฐํ๋ ๋ฐ ์ฌ์ฉํ๋ ๋ถํฌ๋ช ํ ํธ๋ค์ ๋๋ค.
์์:
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shader, source)
- ์
ฐ์ด๋ ๊ฐ์ฒด๋ฅผ ์ป์ผ๋ฉด, ์ด ํจ์๋ฅผ ์ฌ์ฉํ์ฌ GLSL ์์ค ์ฝ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
source๋งค๊ฐ๋ณ์๋ ์ ์ฒด GLSL ํ๋ก๊ทธ๋จ์ ํฌํจํ๋ JavaScript ๋ฌธ์์ด์ ๋๋ค. - ์ธ๋ถ ํ์ผ(์: ๋ฒํ
์ค ์
ฐ์ด๋์ฉ
.vert, ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ฉ.frag)์์ ์ ฐ์ด๋ ์ฝ๋๋ฅผ ๋ก๋ํ ๋ค์ JavaScript ๋ฌธ์์ด๋ก ์ฝ์ด์ค๋ ๊ฒ์ด ์ผ๋ฐ์ ์ธ ๊ดํ์ ๋๋ค. - ๋๋ผ์ด๋ฒ๋ ์ด ์์ค ์ฝ๋๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ ์ฅํ๊ณ ๋ค์ ๋จ๊ณ๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
GLSL ์์ค ๋ฌธ์์ด ์์:
const vsSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
const fsSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
`;
// Attach to shader objects
gl.shaderSource(vertexShader, vsSource);
gl.shaderSource(fragmentShader, fsSource);
2๋จ๊ณ: ๊ฐ๋ณ ์ ฐ์ด๋ ์ปดํ์ผ
์์ค ์ฝ๋๊ฐ ์ ๊ณต๋๋ฉด ๋ค์ ๋ ผ๋ฆฌ์ ์ธ ๋จ๊ณ๋ ๊ฐ ์ ฐ์ด๋๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ์ปดํ์ผํ๋ ๊ฒ์ ๋๋ค. ์ด ๋จ๊ณ์์ GLSL ์ฝ๋๋ ๊ตฌ๋ฌธ ์ค๋ฅ๋ฅผ ๊ฒ์ฌํ๊ณ ๊ตฌ๋ฌธ ๋ถ์๋๋ฉฐ, GPU ๋๋ผ์ด๋ฒ๊ฐ ์ดํดํ๊ณ ์ต์ ํํ ์ ์๋ ์ค๊ฐ ํํ(IR)์ผ๋ก ๋ณํ๋ฉ๋๋ค.
gl.compileShader(shader)
- ์ด ํจ์๋ ์ง์ ๋
shader๊ฐ์ฒด์ ๋ํ ์ปดํ์ผ ํ๋ก์ธ์ค๋ฅผ ์์ํฉ๋๋ค. - GPU ๋๋ผ์ด๋ฒ์ GLSL ์ปดํ์ผ๋ฌ๊ฐ ์ธ์๋ฐ์ ์ดํ ๋ถ์, ๊ตฌ๋ฌธ ๋ถ์, ์๋ฏธ ๋ถ์ ๋ฐ ๋์ GPU ์ํคํ ์ฒ์ ํนํ๋ ์ด๊ธฐ ์ต์ ํ ํจ์ค๋ฅผ ์ํํฉ๋๋ค.
- ์ฑ๊ณตํ๋ฉด ์ ฐ์ด๋ ๊ฐ์ฒด๋ ์ด์ ์ปดํ์ผ๋ ์คํ ๊ฐ๋ฅํ ํํ์ GLSL ์ฝ๋๋ฅผ ๋ณด์ ํฉ๋๋ค. ์คํจํ๋ฉด ๋ฐ์ํ ์ค๋ฅ์ ๋ํ ์ ๋ณด๊ฐ ํฌํจ๋ฉ๋๋ค.
์ค์: ์ปดํ์ผ ์ค๋ฅ ํ์ธ
์ด๊ฒ์ ๋๋ฒ๊น ์ ์์ด ๊ฐ์ฅ ์ค์ํ ๋จ๊ณ์ผ ์ ์์ต๋๋ค. ์ ฐ์ด๋๋ ์ข ์ข ์ฌ์ฉ์ ์์คํ ์์ JIT(Just-In-Time) ๋ฐฉ์์ผ๋ก ์ปดํ์ผ๋ฉ๋๋ค. ์ด๋ GLSL ์ฝ๋์ ๊ตฌ๋ฌธ ๋๋ ์๋ฏธ ์ค๋ฅ๊ฐ ์ด ๋จ๊ณ์์๋ง ๋ฐ๊ฒฌ๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๊ฒฌ๊ณ ํ ์ค๋ฅ ํ์ธ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค:
gl.getShaderParameter(shader, gl.COMPILE_STATUS): ์ปดํ์ผ์ด ์ฑ๊ณตํ๋ฉดtrue๋ฅผ, ๊ทธ๋ ์ง ์์ผ๋ฉดfalse๋ฅผ ๋ฐํํฉ๋๋ค.gl.getShaderInfoLog(shader): ์ปดํ์ผ์ด ์คํจํ๋ฉด ์ด ํจ์๋ ์ค ๋ฒํธ ๋ฐ ์ค๋ช ์ ํฌํจํ ์์ธํ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ด๊ธด ๋ฌธ์์ด์ ๋ฐํํฉ๋๋ค. ์ด ๋ก๊ทธ๋ GLSL ์ฝ๋ ๋๋ฒ๊น ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์: ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํ์ผ ํจ์
function compileShader(gl, source, type) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const info = gl.getShaderInfoLog(shader);
gl.deleteShader(shader); // Clean up failed shader
throw new Error(`Could not compile WebGL shader: ${info}`);
}
return shader;
}
// Usage:
const vertexShader = compileShader(gl, vsSource, gl.VERTEX_SHADER);
const fragmentShader = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);
์ด ๋จ๊ณ์ ๋ ๋ฆฝ์ ์ธ ํน์ฑ์ ๋ค๋จ๊ณ ํ์ดํ๋ผ์ธ์ ํต์ฌ ์ธก๋ฉด์ ๋๋ค. ๊ฐ๋ฐ์๋ ๊ฐ๋ณ ์ ฐ์ด๋๋ฅผ ํ ์คํธํ๊ณ ๋๋ฒ๊น ํ์ฌ ๋ฒํ ์ค ์ ฐ์ด๋ ๋๋ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ํน์ ํ ๋ฌธ์ ์ ๋ํ ๋ช ํํ ํผ๋๋ฐฑ์ ์ป์ ํ ๋จ์ผ ํ๋ก๊ทธ๋จ์ผ๋ก ๊ฒฐํฉ์ ์๋ํ ์ ์์ต๋๋ค.
3๋จ๊ณ: ํ๋ก๊ทธ๋จ ์์ฑ ๋ฐ ์ ฐ์ด๋ ์ฒจ๋ถ
๊ฐ๋ณ ์ ฐ์ด๋๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผํ ํ, ๋ค์ ๋จ๊ณ๋ ์ด ์ ฐ์ด๋๋ค์ ํจ๊ป ๋งํนํ "ํ๋ก๊ทธ๋จ" ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋๋ค. ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ GPU๊ฐ ๋ ๋๋ง์ ์ฌ์ฉํ ์์ ํ ์คํ ๊ฐ๋ฅํ ์ ฐ์ด๋ ์(ํ๋์ ๋ฒํ ์ค ์ ฐ์ด๋์ ํ๋์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋)์ ๋ด๋ ์ปจํ ์ด๋ ์ญํ ์ ํฉ๋๋ค.
gl.createProgram()
- ์ด ํจ์๋ ๋น ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์ ฐ์ด๋ ๊ฐ์ฒด์ ๋ง์ฐฌ๊ฐ์ง๋ก, WebGL ์ปจํ ์คํธ์ ์ํด ๊ด๋ฆฌ๋๋ ๋ถํฌ๋ช ํ ํธ๋ค์ ๋๋ค.
- ๋จ์ผ WebGL ์ปจํ ์คํธ๋ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ ์ ์์ด ๋์ผํ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ๋ค์ํ ๋ ๋๋ง ํจ๊ณผ ๋๋ ํจ์ค๋ฅผ ํ์ฉํฉ๋๋ค.
์์:
const shaderProgram = gl.createProgram();
gl.attachShader(program, shader)
- ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ฅผ ์ป์ผ๋ฉด, ์ปดํ์ผ๋ ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๋ฅผ ๊ฐ์ฒด์ ์ฒจ๋ถํฉ๋๋ค.
- ์ค์ํ๊ฒ๋, ์ ํจํ๊ณ ๋งํน ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ์ด ๋๋ ค๋ฉด ๋ฒํ ์ค ์ ฐ์ด๋์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋ ๋ ๋ค ํ๋ก๊ทธ๋จ์ ์ฒจ๋ถํด์ผ ํฉ๋๋ค.
์์:
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
์ด ์์ ์์ ํ๋ก๊ทธ๋จ ๊ฐ์ฒด๋ ๋จ์ํ ์ด๋ค ์ปดํ์ผ๋ ์ ฐ์ด๋๋ฅผ ๊ฒฐํฉํด์ผ ํ๋์ง ์๊ณ ์์ต๋๋ค. ์ค์ ๊ฒฐํฉ ๋ฐ ์ต์ข ์คํ ํ์ผ ์์ฑ์ ์์ง ๋ฐ์ํ์ง ์์์ต๋๋ค.
4๋จ๊ณ: ํ๋ก๊ทธ๋จ ๋งํน โ ์๋ํ ํตํฉ
์ด๊ฒ์ ๊ฐ๋ณ์ ์ผ๋ก ์ปดํ์ผ๋ ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๊ฐ ํจ๊ป ๋ชจ์ด๊ณ ํตํฉ๋์ด GPU์์ ์คํํ ์ ์๋ ๋จ์ผ ์คํ ํ๋ก๊ทธ๋จ์ผ๋ก ์ต์ ํ๋๋ ์ค์ํ ๋จ๊ณ์ ๋๋ค. ๋งํน์ ๋ฒํ ์ค ์ ฐ์ด๋์ ์ถ๋ ฅ์ด ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ์ ๋ ฅ์ ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋๋์ง ํด๊ฒฐํ๊ณ , ๋ฆฌ์์ค ์์น๋ฅผ ํ ๋นํ๋ฉฐ, ์ต์ข ์ ์ธ ์ ์ฒด ํ๋ก๊ทธ๋จ ์ต์ ํ๋ฅผ ์ํํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค.
gl.linkProgram(program)
- ์ด ํจ์๋ ์ง์ ๋
program๊ฐ์ฒด์ ๋ํ ๋งํน ํ๋ก์ธ์ค๋ฅผ ์์ํฉ๋๋ค. - ๋งํน ์ค GPU ๋๋ผ์ด๋ฒ๋ ์ฌ๋ฌ ๊ฐ์ง ์ค์ํ ์์ ์ ์ํํฉ๋๋ค:
- ๋ฒ ๋ฆฌ์(Varying) ํด์๋: ๋ฒํ
์ค ์
ฐ์ด๋์ ์ ์ธ๋
varying(WebGL 1.0) ๋๋out/in(WebGL 2.0) ๋ณ์๋ฅผ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ํด๋นin๋ณ์์ ์ผ์น์ํต๋๋ค. ์ด ๋ณ์๋ค์ ํ๋ฆฌ๋ฏธํฐ๋ธ ํ๋ฉด์ ๊ฐ๋ก์ง๋ฌ ์ ์ ์์ ํ๋๊ทธ๋จผํธ๋ก ๋ฐ์ดํฐ(ํ ์ค์ฒ ์ขํ, ๋ ธ๋ฉ ๋๋ ์์ ๋ฑ) ๋ณด๊ฐ์ ์ฉ์ดํ๊ฒ ํฉ๋๋ค. - ์์ฑ(Attribute) ์์น ํ ๋น: ๋ฒํ
์ค ์
ฐ์ด๋์์ ์ฌ์ฉ๋๋
attribute๋ณ์์ ์ซ์ ์์น๋ฅผ ํ ๋นํฉ๋๋ค. ์ด ์์น๋ JavaScript ์ฝ๋๊ฐ GPU์ ์ด๋ค ์ ์ ๋ฒํผ ๋ฐ์ดํฐ๊ฐ ์ด๋ค ์์ฑ์ ํด๋นํ๋์ง ์๋ ค์ฃผ๋ ๋ฐฉ์์ ๋๋ค. GLSL์์layout(location = X)(WebGL 2.0)๋ฅผ ์ฌ์ฉํ์ฌ ๋ช ์์ ์ผ๋ก ์์น๋ฅผ ์ง์ ํ๊ฑฐ๋gl.getAttribLocation()(WebGL 1.0 ๋ฐ 2.0)๋ฅผ ํตํด ์ฟผ๋ฆฌํ ์ ์์ต๋๋ค. - ์ ๋ํผ(Uniform) ์์น ํ ๋น: ์ ์ฌํ๊ฒ,
uniform๋ณ์(๋ณํ ํ๋ ฌ, ๊ด์ ์์น ๋๋ ๋๋ก์ฐ ํธ์ถ์ ๋ชจ๋ ์ ์ /ํ๋๊ทธ๋จผํธ์์ ์ผ์ ํ๊ฒ ์ ์ง๋๋ ์์๊ณผ ๊ฐ์ ์ ์ญ ์ ฐ์ด๋ ๋งค๊ฐ๋ณ์)์ ์์น๋ฅผ ํ ๋นํฉ๋๋ค. ์ด๋ค์gl.getUniformLocation()์ ํตํด ์ฟผ๋ฆฌ๋ฉ๋๋ค. - ์ ์ฒด ํ๋ก๊ทธ๋จ ์ต์ ํ: ๋๋ผ์ด๋ฒ๋ ๋ ์ ฐ์ด๋๋ฅผ ํจ๊ป ๊ณ ๋ คํ์ฌ ์ถ๊ฐ ์ต์ ํ๋ฅผ ์ํํ ์ ์์ผ๋ฉฐ, ์ฌ์ฉ๋์ง ์๋ ์ฝ๋ ๊ฒฝ๋ก๋ฅผ ์ ๊ฑฐํ๊ฑฐ๋ ๊ณ์ฐ์ ๋จ์ํํ ์ ์์ต๋๋ค.
- ์ต์ข ์คํ ํ์ผ ์์ฑ: ๋งํฌ๋ ํ๋ก๊ทธ๋จ์ GPU์ ๋ค์ดํฐ๋ธ ๋จธ์ ์ฝ๋๋ก ๋ฒ์ญ๋์ด ํ๋์จ์ด์ ๋ก๋๋ฉ๋๋ค.
์ค์: ๋งํน ์ค๋ฅ ํ์ธ
์ปดํ์ผ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋งํน๋ ์คํจํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ข ์ข ๋ฒํ ์ค ์ ฐ์ด๋์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋ ๊ฐ์ ๋ถ์ผ์น ๋๋ ๋น์ผ๊ด์ฑ ๋๋ฌธ์ ๋๋ค. ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ํ์์ ์ ๋๋ค:
gl.getProgramParameter(program, gl.LINK_STATUS): ๋งํน์ด ์ฑ๊ณตํ๋ฉดtrue๋ฅผ, ๊ทธ๋ ์ง ์์ผ๋ฉดfalse๋ฅผ ๋ฐํํฉ๋๋ค.gl.getProgramInfoLog(program): ๋งํน์ด ์คํจํ๋ฉด ์ด ํจ์๋ ๋ถ์ผ์นํ๋ varying ์ ํ, ์ ์ธ๋์ง ์์ ๋ณ์ ๋๋ ํ๋์จ์ด ๋ฆฌ์์ค ํ๋ ์ด๊ณผ์ ๊ฐ์ ๋ฌธ์ ๋ฅผ ํฌํจํ ์ ์๋ ์์ธํ ์ค๋ฅ ๋ก๊ทธ๋ฅผ ๋ฐํํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ๋งํน ์ค๋ฅ:
- ๋ถ์ผ์นํ๋ ๋ฒ ๋ฆฌ์(Varyings): ๋ฒํ
์ค ์
ฐ์ด๋์ ์ ์ธ๋
varying๋ณ์์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ํด๋นํ๋in๋ณ์(๋์ผํ ์ด๋ฆ๊ณผ ์ ํ)๊ฐ ์๋ ๊ฒฝ์ฐ. - ์ ์๋์ง ์์ ๋ณ์:
uniform๋๋attribute๊ฐ ํ ์ ฐ์ด๋์์ ์ฐธ์กฐ๋์ง๋ง ๋ค๋ฅธ ์ ฐ์ด๋์์ ์ ์ธ๋๊ฑฐ๋ ์ฌ์ฉ๋์ง ์๊ฑฐ๋, ์คํ๊ฐ ์๋ ๊ฒฝ์ฐ. - ๋ฆฌ์์ค ์ ํ: GPU๊ฐ ์ง์ํ๋ ๊ฒ๋ณด๋ค ๋ ๋ง์ ์์ฑ, ๋ฒ ๋ฆฌ์ ๋๋ ์ ๋ํผ์ ์ฌ์ฉํ๋ ค๊ณ ์๋ํ๋ ๊ฒฝ์ฐ.
์ค์ฉ์ ์ธ ์์: ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ ์์ฑ ํจ์
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const info = gl.getProgramInfoLog(program);
gl.deleteProgram(program); // Clean up failed program
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
throw new Error(`Could not link WebGL program: ${info}`);
}
return program;
}
// Usage:
const shaderProgram = createProgram(gl, vertexShader, fragmentShader);
5๋จ๊ณ: ํ๋ก๊ทธ๋จ ์ ํจ์ฑ ๊ฒ์ฌ (์ ํ ์ฌํญ์ด์ง๋ง ๊ถ์ฅ)
๋งํน์ ์ ฐ์ด๋๊ฐ ์ ํจํ ํ๋ก๊ทธ๋จ์ผ๋ก ๊ฒฐํฉ๋ ์ ์๋๋ก ๋ณด์ฅํ์ง๋ง, WebGL์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ์ถ๊ฐ์ ์ธ ์ ํ์ ๋จ๊ณ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๋จ๊ณ๋ ์ปดํ์ผ ๋๋ ๋งํน ์ค์๋ ๋ช ํํ์ง ์์ ์ ์๋ ๋ฐํ์ ์ค๋ฅ๋ ๋นํจ์จ์ฑ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
gl.validateProgram(program)
- ์ด ํจ์๋ ํ์ฌ WebGL ์ํ์์ ํ๋ก๊ทธ๋จ์ด ์คํ ๊ฐ๋ฅํ์ง ํ์ธํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ ์ ์์ต๋๋ค:
gl.enableVertexAttribArray()๋ฅผ ํตํด ํ์ฑํ๋์ง ์์ ์์ฑ ์ฌ์ฉ.- ์ ฐ์ด๋์์ ์ ์ธ๋์์ง๋ง ์ ํ ์ฌ์ฉ๋์ง ์๋ ์ ๋ํผ. ์ผ๋ถ ๋๋ผ์ด๋ฒ์ ์ํด ์ต์ ํ๋ ์ ์์ง๋ง ๋ค๋ฅธ ๋๋ผ์ด๋ฒ์์๋ ๊ฒฝ๊ณ ๋ ์๊ธฐ์น ์์ ๋์์ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ์ํ๋ฌ ์ ํ ๋ฐ ํ ์ค์ฒ ์ ๋ ๋ฌธ์ .
- ์ ํจ์ฑ ๊ฒ์ฌ๋ ๋น๊ต์ ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ผ ์ ์์ผ๋ฏ๋ก, ์ผ๋ฐ์ ์ผ๋ก ํ๋ก๋์ ๋ณด๋ค๋ ๊ฐ๋ฐ ๋ฐ ๋๋ฒ๊น ๋น๋์ ๊ถ์ฅ๋ฉ๋๋ค.
์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ์ค๋ฅ ํ์ธ:
gl.getProgramParameter(program, gl.VALIDATE_STATUS): ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์ฑ๊ณตํ๋ฉดtrue๋ฅผ ๋ฐํํฉ๋๋ค.gl.getProgramInfoLog(program): ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์คํจํ๋ฉด ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
6๋จ๊ณ: ํ์ฑํ ๋ฐ ์ฌ์ฉ
ํ๋ก๊ทธ๋จ์ด ์ฑ๊ณต์ ์ผ๋ก ์ปดํ์ผ, ๋งํน, ๊ทธ๋ฆฌ๊ณ ์ ํ์ ์ผ๋ก ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๊ฑฐ์น๋ฉด ๋ ๋๋ง์ ์ฌ์ฉํ ์ค๋น๊ฐ ๋ ๊ฒ์ ๋๋ค.
gl.useProgram(program)
- ์ด ํจ์๋ ์ง์ ๋
program๊ฐ์ฒด๋ฅผ ํ์ฑํํ์ฌ GPU๊ฐ ํ์ ๋๋ก์ฐ ํธ์ถ์ ์ฌ์ฉํ ํ์ฌ ์ ฐ์ด๋ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ง๋ญ๋๋ค.
ํ๋ก๊ทธ๋จ์ ํ์ฑํํ ํ์๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํฉ๋๋ค:
- ์์ฑ ๋ฐ์ธ๋ฉ:
gl.getAttribLocation()์ ์ฌ์ฉํ์ฌ ์์ฑ ๋ณ์์ ์์น๋ฅผ ์ฐพ์ ๋ค์,gl.enableVertexAttribArray()๋ฐgl.vertexAttribPointer()๋ก ์ ์ ๋ฒํผ๋ฅผ ๊ตฌ์ฑํ์ฌ ์ด ์์ฑ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต๊ธํฉ๋๋ค. - ์ ๋ํผ ์ค์ :
gl.getUniformLocation()์ ์ฌ์ฉํ์ฌ ์ ๋ํผ ๋ณ์์ ์์น๋ฅผ ์ฐพ์ ๋ค์,gl.uniform1f(),gl.uniformMatrix4fv()๋ฑ๊ณผ ๊ฐ์ ํจ์๋ก ํด๋น ๊ฐ์ ์ค์ ํฉ๋๋ค. - ๋๋ก์ฐ ํธ์ถ ๋ฐํ: ๋ง์ง๋ง์ผ๋ก
gl.drawArrays()๋๋gl.drawElements()๋ฅผ ํธ์ถํ์ฌ ํ์ฑ ํ๋ก๊ทธ๋จ๊ณผ ๊ตฌ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ๋ ๋๋งํฉ๋๋ค.
"๋ค๋จ๊ณ"์ ์ฅ์ : ์ด ์ํคํ ์ฒ๋ฅผ ์ฌ์ฉํ๋ ์ด์
๋ค๋จ๊ณ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ๊ฒ๋ณด๊ธฐ์๋ ๋ณต์กํด ๋ณด์ด์ง๋ง, WebGL๊ณผ ์ผ๋ฐ์ ์ธ ํ๋ ๊ทธ๋ํฝ์ค API์ ๊ฒฌ๊ณ ์ฑ๊ณผ ์ ์ฐ์ฑ์ ๋ท๋ฐ์นจํ๋ ์๋นํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
1. ๋ชจ๋์ฑ ๋ฐ ์ฌ์ฌ์ฉ์ฑ:
- ๋ฒํ ์ค ์ ฐ์ด๋์ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๋ฅผ ๋ณ๋๋ก ์ปดํ์ผํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์ด๋ค์ ์กฐํฉํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ค์ํ 3D ๋ชจ๋ธ์ ๋ณํ์ ์ฒ๋ฆฌํ๋ ํ๋์ ์ผ๋ฐ ๋ฒํ ์ค ์ ฐ์ด๋๋ฅผ ๊ฐ์ง๊ณ ์ฌ๋ฌ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ์ง์ ์ด๋ฃจ์ด ๋ค๋ฅธ ์๊ฐ ํจ๊ณผ(์: ํ์ฐ ์กฐ๋ช , ํ ์กฐ๋ช , ์ ์ ฐ์ด๋ฉ ๋๋ ํ ์ค์ฒ ๋งคํ)๋ฅผ ์ป์ ์ ์์ต๋๋ค. ์ด๋ ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ๊ฐ๋ฐ ๋ฐ ์ ์ง ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ์ฌ ๋ชจ๋์ฑ๊ณผ ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ด์งํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๊ฑด์ถ ์๊ฐํ ํ์ฌ๋ ๊ฑด๋ฌผ ๋ชจ๋ธ์ ํ์ํ๊ธฐ ์ํด ๋จ์ผ ๋ฒํ ์ค ์ ฐ์ด๋๋ฅผ ์ฌ์ฉํ์ง๋ง, ๋ค๋ฅธ ์ฌ๋ฃ ๋ง๊ฐ(๋๋ฌด, ์ ๋ฆฌ, ๊ธ์)์ด๋ ์กฐ๋ช ์กฐ๊ฑด์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๋ฅผ ๊ต์ฒดํ ์ ์์ต๋๋ค.
2. ์ค๋ฅ ๊ฒฉ๋ฆฌ ๋ฐ ๋๋ฒ๊น :
- ํ๋ก์ธ์ค๋ฅผ ๋ณ๊ฐ์ ์ปดํ์ผ ๋ฐ ๋งํน ๋จ๊ณ๋ก ๋๋๋ฉด ์ค๋ฅ๋ฅผ ์ฐพ์๋ด๊ณ ๋๋ฒ๊น
ํ๊ธฐ๊ฐ ํจ์ฌ ์ฌ์์ง๋๋ค. GLSL์ ๊ตฌ๋ฌธ ์ค๋ฅ๊ฐ ์์ผ๋ฉด
gl.compileShader()๊ฐ ์คํจํ๊ณgl.getShaderInfoLog()๊ฐ ์ด๋ค ์ ฐ์ด๋์ ์ค ๋ฒํธ์ ๋ฌธ์ ๊ฐ ์๋์ง ์ ํํ ์๋ ค์ค ๊ฒ์ ๋๋ค. - ๊ฐ๋ณ ์
ฐ์ด๋๋ ์ปดํ์ผ๋์ง๋ง ํ๋ก๊ทธ๋จ์ด ๋งํน์ ์คํจํ๋ฉด
gl.getProgramInfoLog()๋ ๋ถ์ผ์นํ๋varying๋ณ์์ ๊ฐ์ ์ ฐ์ด๋ ๊ฐ์ ์ํธ ์์ฉ๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ๋ํ๋ผ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ์ธ๋ถํ๋ ํผ๋๋ฐฑ ๋ฃจํ๋ ๋๋ฒ๊น ํ๋ก์ธ์ค๋ฅผ ํฌ๊ฒ ๊ฐ์ํํฉ๋๋ค.
3. ํ๋์จ์ด๋ณ ์ต์ ํ:
- GPU ๋๋ผ์ด๋ฒ๋ ๋ค์ํ ํ๋์จ์ด์์ ์ต๋ ์ฑ๋ฅ์ ์ถ์ถํ๋๋ก ์ค๊ณ๋ ๊ณ ๋๋ก ๋ณต์กํ ์ํํธ์จ์ด์ ๋๋ค. ๋ค๋จ๊ณ ์ ๊ทผ ๋ฐฉ์์ ๋๋ผ์ด๋ฒ๊ฐ ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ๋จ๊ณ์ ๋ํด ๋ ๋ฆฝ์ ์ผ๋ก ํน์ ์ต์ ํ๋ฅผ ์ํํ ๋ค์, ๋งํน ๋จ๊ณ์์ ์ถ๊ฐ์ ์ธ ์ ์ฒด ํ๋ก๊ทธ๋จ ์ต์ ํ๋ฅผ ์ ์ฉํ ์ ์๋๋ก ํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋๋ผ์ด๋ฒ๋ ํน์ ์ ๋ํผ์ด ๋ฒํ ์ค ์ ฐ์ด๋์์๋ง ์ฌ์ฉ๋๋ค๋ ๊ฒ์ ๊ฐ์งํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ ๊ทผ ๊ฒฝ๋ก๋ฅผ ์ต์ ํํ ์ ์์ผ๋ฉฐ, ๋๋ ๋งํน ์ค์ ์ ๊ฑฐํ ์ ์๋ ์ฌ์ฉ๋์ง ์๋ varying ๋ณ์๋ฅผ ์๋ณํ์ฌ ๋ฐ์ดํฐ ์ ์ก ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
- ์ด๋ฌํ ์ ์ฐ์ฑ์ GPU ๊ณต๊ธ์ ์ฒด๊ฐ ํน์ ํ๋์จ์ด์ ๋ํ ๊ณ ๋๋ก ์ ๋ฌธํ๋ ๋จธ์ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋๋ก ํ์ฌ, ๊ณ ์ฑ๋ฅ ๋ฐ์คํฌํฑ GPU๋ถํฐ ์ ์ธ๊ณ ์ค๋งํธํฐ ๋ฐ ํ๋ธ๋ฆฟ์ ์๋ ํตํฉ ๋ชจ๋ฐ์ผ ์นฉ์ ์ ์ด๋ฅด๊ธฐ๊น์ง ๊ด๋ฒ์ํ ์ฅ์น์์ ๋ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
4. ๋ฆฌ์์ค ๊ด๋ฆฌ:
- ๋๋ผ์ด๋ฒ๋ ๋ด๋ถ ์ ฐ์ด๋ ๋ฆฌ์์ค๋ฅผ ๋ณด๋ค ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ปดํ์ผ๋ ์ ฐ์ด๋์ ์ค๊ฐ ํํ์ ์บ์๋ ์ ์์ต๋๋ค. ๋ ํ๋ก๊ทธ๋จ์ด ๋์ผํ ๋ฒํ ์ค ์ ฐ์ด๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ๋๋ผ์ด๋ฒ๋ ํ ๋ฒ๋ง ์ฌ์ปดํ์ผํ ๋ค์ ๋ค๋ฅธ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ์ฐ๊ฒฐํ๋ฉด ๋ฉ๋๋ค.
5. ์ด์์ฑ ๋ฐ ํ์คํ:
- ์ด ํ์ดํ๋ผ์ธ ์ํคํ ์ฒ๋ WebGL์๋ง ๊ณ ์ ํ ๊ฒ์ด ์๋๋๋ค. OpenGL ES์์ ์์๋์์ผ๋ฉฐ ํ๋ ๊ทธ๋ํฝ์ค API(์: DirectX, Vulkan, Metal, WebGPU)์ ํ์ค ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ด๋ฌํ ํ์คํ๋ ๊ทธ๋ํฝ์ค ํ๋ก๊ทธ๋๋จธ์๊ฒ ์ผ๊ด๋ ์ ์ ์ ๋ชจ๋ธ์ ๋ณด์ฅํ์ฌ ํ๋ซํผ ๋ฐ API ๊ฐ์ ๊ธฐ์ ์ ์ด์ ํ ์ ์๋๋ก ํฉ๋๋ค. ์น ํ์ค์ธ WebGL ์ฌ์์ ์ด ํ์ดํ๋ผ์ธ์ด ์ ์ธ๊ณ ๋ค์ํ ๋ธ๋ผ์ฐ์ ๋ฐ ์ด์ ์ฒด์ ์์ ์์ธก ๊ฐ๋ฅํ๊ฒ ์๋ํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ๊ณ ๊ธ ๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ์ต์ ํํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ ์ธ๊ณ์ ๋ค์ํ ์ฌ์ฉ์ ํ๊ฒฝ์์ ๊ณ ํ์ง์ ๊ณ ์ฑ๋ฅ WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ณตํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ๊ณ ๊ธ ๊ณ ๋ ค ์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค:
์ ฐ์ด๋ ์บ์ฑ
ํ๋ ๋ธ๋ผ์ฐ์ ์ GPU ๋๋ผ์ด๋ฒ๋ ์ปดํ์ผ๋ ์ ฐ์ด๋ ํ๋ก๊ทธ๋จ์ ๋ํ ๋ด๋ถ ์บ์ฑ ๋ฉ์ปค๋์ฆ์ ์ข ์ข ๊ตฌํํฉ๋๋ค. ์ฌ์ฉ์๊ฐ WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ ๋ฐฉ๋ฌธํ๊ณ ์ ฐ์ด๋ ์์ค ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋์ง ์์ ๊ฒฝ์ฐ, ๋ธ๋ผ์ฐ์ ๋ ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ํ๋ก๊ทธ๋จ์ ์บ์์์ ์ง์ ๋ก๋ํ์ฌ ์์ ์๊ฐ์ ํฌ๊ฒ ๋จ์ถํ ์ ์์ต๋๋ค. ์ด๋ ํนํ ๋๋ฆฐ ๋คํธ์ํฌ๋ ์ฑ๋ฅ์ด ๋ฎ์ ์ฅ์น๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์์๊ฒ ์ ๋ฆฌํ๋ฉฐ, ํ์ ๋ฐฉ๋ฌธ ์ ๊ณ์ฐ ์ค๋ฒํค๋๋ฅผ ์ต์ํํฉ๋๋ค.
- ์๋ฏธ: ์ ฐ์ด๋ ์์ค ์ฝ๋ ๋ฌธ์์ด์ด ์ผ๊ด์ ์ธ์ง ํ์ธํ์ธ์. ์ฌ์ํ ๊ณต๋ฐฑ ๋ณ๊ฒฝ์กฐ์ฐจ ์บ์๋ฅผ ๋ฌดํจํํ ์ ์์ต๋๋ค.
- ๊ฐ๋ฐ vs. ํ๋ก๋์ : ๊ฐ๋ฐ ์ค์๋ ์๋ก์ด ์ ฐ์ด๋ ๋ฒ์ ์ด ํญ์ ๋ก๋๋๋๋ก ์๋์ ์ผ๋ก ์บ์๋ฅผ ๋ฌดํจํํ ์ ์์ต๋๋ค. ํ๋ก๋์ ์์๋ ์บ์ฑ์ ์์กดํ๊ณ ์ด์ ์ ํ์ฉํ์ธ์.
์ ฐ์ด๋ ํซ-์ค์/๋ผ์ด๋ธ ๋ฆฌ๋ก๋ฉ
๋น ๋ฅธ ๊ฐ๋ฐ ์ฃผ๊ธฐ, ํนํ ์๊ฐ ํจ๊ณผ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ๊ฐ์ ํ ๋ ์ ์ฒด ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ์ง ์๊ณ ์ ฐ์ด๋๋ฅผ ์ ๋ฐ์ดํธํ๋ ๊ธฐ๋ฅ(ํซ ์ค์ ๋๋ ๋ผ์ด๋ธ ๋ฆฌ๋ก๋ฉ์ผ๋ก ์๋ ค์ง)์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
- ์ ฐ์ด๋ ์์ค ํ์ผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํฉ๋๋ค.
- ์๋ก์ด ์ ฐ์ด๋๋ฅผ ์ปดํ์ผํ๊ณ ์๋ก์ด ํ๋ก๊ทธ๋จ์ ๋งํนํฉ๋๋ค.
- ์ฑ๊ณตํ๋ฉด ๋ ๋๋ง ๋ฃจํ์์
gl.useProgram()์ ์ฌ์ฉํ์ฌ ์ด์ ํ๋ก๊ทธ๋จ์ ์ ํ๋ก๊ทธ๋จ์ผ๋ก ๊ต์ฒดํฉ๋๋ค. - ์ด๋ ์ ฐ์ด๋ ๊ฐ๋ฐ ์๋๋ฅผ ํฌ๊ฒ ๋์ฌ ์ํฐ์คํธ์ ๊ฐ๋ฐ์๊ฐ ์ง๋ฆฌ์ ์์น๋ ๊ฐ๋ฐ ํ๊ฒฝ์ ๊ด๊ณ์์ด ์ฆ์ ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ ์ ์๋๋ก ํฉ๋๋ค.
์ ฐ์ด๋ ๋ณํ ๋ฐ ์ ์ฒ๋ฆฌ๊ธฐ ์ง์๋ฌธ
๊ด๋ฒ์ํ ํ๋์จ์ด ๊ธฐ๋ฅ์ ์ง์ํ๊ฑฐ๋ ๋ค์ํ ์๊ฐ์ ํ์ง ์ค์ ์ ์ ๊ณตํ๊ธฐ ์ํด ๊ฐ๋ฐ์๋ ์ข
์ข
์
ฐ์ด๋ ๋ณํ์ ๋ง๋ญ๋๋ค. ์์ ํ ๋ณ๊ฐ์ GLSL ํ์ผ์ ์์ฑํ๋ ๋์ , C/C++ ์ ์ฒ๋ฆฌ๊ธฐ ๋งคํฌ๋ก์ ์ ์ฌํ GLSL ์ ์ฒ๋ฆฌ๊ธฐ ์ง์๋ฌธ(์: #define, #ifdef, #ifndef, #endif)์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์:
#ifdef USE_PHONG_SHADING
// Phong lighting calculations
#else
// Basic diffuse lighting calculations
#endif
gl.shaderSource()๋ฅผ ํธ์ถํ๊ธฐ ์ ์ GLSL ์์ค ๋ฌธ์์ด์ #define USE_PHONG_SHADING์ ์์ ์ถ๊ฐํ์ฌ, ๋ค์ํ ํจ๊ณผ ๋๋ ์ฑ๋ฅ ๋ชฉํ๋ฅผ ์ํด ๋์ผํ ์
ฐ์ด๋์ ๋ค๋ฅธ ๋ฒ์ ์ ์ปดํ์ผํ ์ ์์ต๋๋ค. ์ด๋ ๊ณ ์ฑ๋ฅ ๊ฒ์ PC๋ถํฐ ๋ณด๊ธํ ๋ชจ๋ฐ์ผ ํฐ์ ์ด๋ฅด๊ธฐ๊น์ง ๋ค์ํ ์ฅ์น ์ฌ์์ ๊ฐ์ง ์ ์ธ๊ณ ์ฌ์ฉ์ ๊ธฐ๋ฐ์ ๋์์ผ๋ก ํ๋ ์ ํ๋ฆฌ์ผ์ด์
์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ฑ๋ฅ ์ต์ ํ
- ์ปดํ์ผ/๋งํน ์ต์ํ: ์ ํ๋ฆฌ์ผ์ด์ ์๋ช ์ฃผ๊ธฐ ๋ด์์ ์ ฐ์ด๋๋ฅผ ๋ถํ์ํ๊ฒ ๋ค์ ์ปดํ์ผํ๊ฑฐ๋ ๋ค์ ๋งํนํ๋ ๊ฒ์ ํผํ์ญ์์ค. ์์ ์ ๋๋ ์ ฐ์ด๋๊ฐ ์ค์ ๋ก ๋ณ๊ฒฝ๋ ๋ ํ ๋ฒ๋ง ์ํํ์ญ์์ค.
- ํจ์จ์ ์ธ GLSL: ๊ฐ๊ฒฐํ๊ณ ์ต์ ํ๋ GLSL ์ฝ๋๋ฅผ ์์ฑํ์ญ์์ค. ๋ณต์กํ ๋ถ๊ธฐ๋ฅผ ํผํ๊ณ , ๋ด์ฅ ํจ์๋ฅผ ์ ํธํ๋ฉฐ, ํนํ ๋ชจ๋ฐ์ผ ์ฅ์น์์ GPU ์ฌ์ดํด ๋ฐ ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ์ ์ ์ฝํ๊ธฐ ์ํด ์ ์ ํ ์ ๋ฐ๋ ํ์ ์(
lowp,mediump,highp)๋ฅผ ์ฌ์ฉํ์ญ์์ค. - ๋๋ก์ฐ ํธ์ถ ๋ฐฐ์น ์ฒ๋ฆฌ: ์ปดํ์ผ๊ณผ ์ง์ ์ ์ธ ๊ด๋ จ์ ์์ง๋ง, ๋จ์ผ ์ ฐ์ด๋ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ ์ ๊ณ ํฐ ๋๋ก์ฐ ํธ์ถ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ง์ ์์ ๋๋ก์ฐ ํธ์ถ๋ณด๋ค ์ผ๋ฐ์ ์ผ๋ก ๋ ์ฑ๋ฅ์ด ์ข์ต๋๋ค. ์ด๋ ๋ ๋๋ง ์ํ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์ค์ ํ๋ ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ ๋ฐ ํฌ๋ก์ค ์ฅ์น ํธํ์ฑ
์น์ ๊ธ๋ก๋ฒ ํน์ฑ์ผ๋ก ์ธํด WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฉ๋ํ ์ฅ์น ๋ฐ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋ฉ๋๋ค. ์ด๋ ํธํ์ฑ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํฉ๋๋ค:
- GLSL ๋ฒ์ : WebGL 1.0์ GLSL ES 1.00์ ์ฌ์ฉํ๊ณ , WebGL 2.0์ GLSL ES 3.00์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ค ๋ฒ์ ์ ๋์์ผ๋ก ํ๋์ง ์ ์ํ์ญ์์ค. WebGL 2.0์ ์ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง ๋ชจ๋ ๊ตฌํ ์ฅ์น์์ ์ง์๋๋ ๊ฒ์ ์๋๋๋ค.
- ๋๋ผ์ด๋ฒ ๋ฒ๊ทธ: ํ์คํ์๋ ๋ถ๊ตฌํ๊ณ GPU ๋๋ผ์ด๋ฒ์ ๋ฏธ๋ฌํ ์ฐจ์ด๋ ๋ฒ๊ทธ๋ก ์ธํด ์ ฐ์ด๋๊ฐ ์ฅ์น๋ง๋ค ๋ค๋ฅด๊ฒ ์๋ํ ์ ์์ต๋๋ค. ๋ค์ํ ํ๋์จ์ด ๋ฐ ๋ธ๋ผ์ฐ์ ์์ ์ฒ ์ ํ ํ ์คํธ๊ฐ ํ์์ ์ ๋๋ค.
- ๊ธฐ๋ฅ ๊ฐ์ง:
gl.getExtension()์ ์ฌ์ฉํ์ฌ ์ ํ์ WebGL ํ์ฅ ๊ธฐ๋ฅ์ ๊ฐ์งํ๊ณ , ํ์ฅ์ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ ๊ธฐ๋ฅ์ ์ ์ง์ ์ผ๋ก ์ ํ์ํค์ญ์์ค.
๋๊ตฌ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๊ธฐ์กด ๋๊ตฌ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ๋ฉด ์ ฐ์ด๋ ์ํฌํ๋ก์ฐ๋ฅผ ํฌ๊ฒ ๊ฐ์ํํ ์ ์์ต๋๋ค:
- ์ ฐ์ด๋ ๋ฒ๋ค๋ฌ/๋ฏธ๋ํ์ด์ด: ๋๊ตฌ๋ GLSL ํ์ผ์ ์ฐ๊ฒฐํ๊ณ ์์ถํ์ฌ ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ ๋ก๋ ์๊ฐ์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
- WebGL ํ๋ ์์ํฌ: Three.js, Babylon.js ๋๋ PlayCanvas์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ ฐ์ด๋ ์ปดํ์ผ ๋ฐ ๊ด๋ฆฌ๋ฅผ ํฌํจํ์ฌ ์ ์์ค WebGL API์ ๋ง์ ๋ถ๋ถ์ ์ถ์ํํฉ๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ ๋๋ ๋๋ฒ๊น ๋ฐ ์ฌ์ฉ์ ์ ์ ํจ๊ณผ๋ฅผ ์ํด ๊ธฐ๋ณธ ํ์ดํ๋ผ์ธ์ ์ดํดํ๋ ๊ฒ์ด ์ฌ์ ํ ์ค์ํฉ๋๋ค.
- ๋๋ฒ๊น ๋๊ตฌ: ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ(์: Chrome์ WebGL Inspector, Firefox์ Shader Editor)๋ ํ์ฑ ์ ฐ์ด๋, ์ ๋ํผ, ์์ฑ ๋ฐ ์ ์ฌ์ ์ค๋ฅ์ ๋ํ ๊ท์คํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ์ฌ ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ฅผ ์ํ ๋๋ฒ๊น ํ๋ก์ธ์ค๋ฅผ ๋จ์ํํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์: ๋ค๋จ๊ณ ์ปดํ์ผ์ ์ฌ์ฉํ ๊ธฐ๋ณธ์ ์ธ WebGL ์ค์
์ด๋ก ์ ์ค์ ๋ก ์ ์ฉํ์ฌ ๊ฐ๋จํ ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋๋ฅผ ์ปดํ์ผํ๊ณ ๋งํนํ์ฌ ๋นจ๊ฐ์ ์ผ๊ฐํ์ ๋ ๋๋งํ๋ ์ต์ํ์ WebGL ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// Global utility to load and compile a shader
function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const info = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
console.error(`Error compiling ${type === gl.VERTEX_SHADER ? 'vertex' : 'fragment'} shader: ${info}`);
return null;
}
return shader;
}
// Global utility to create and link a program
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
if (!vertexShader || !fragmentShader) {
return null;
}
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
const info = gl.getProgramInfoLog(shaderProgram);
gl.deleteProgram(shaderProgram);
console.error(`Error linking shader program: ${info}`);
return null;
}
// Detach and delete shaders after linking; they are no longer needed
// This frees up resources and is a good practice.
gl.detachShader(shaderProgram, vertexShader);
gl.detachShader(shaderProgram, fragmentShader);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
return shaderProgram;
}
// Vertex shader source code
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
}
`;
// Fragment shader source code
const fsSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red color
}
`;
function main() {
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = 640;
canvas.height = 480;
const gl = canvas.getContext('webgl');
if (!gl) {
alert('Unable to initialize WebGL. Your browser or machine may not support it.');
return;
}
// Initialize the shader program
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
if (!shaderProgram) {
return; // Exit if program failed to compile/link
}
// Get attribute location from the linked program
const vertexPositionAttribute = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
// Create a buffer for the triangle's positions.
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5, // Top vertex
-0.5, -0.5, // Bottom-left vertex
0.5, -0.5 // Bottom-right vertex
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// Set clear color to black, fully opaque
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Use the compiled and linked shader program
gl.useProgram(shaderProgram);
// Tell WebGL how to pull the positions from the position buffer
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(
vertexPositionAttribute,
2, // Number of components per vertex attribute (x, y)
gl.FLOAT, // Type of data in the buffer
false, // Normalize
0, // Stride
0 // Offset
);
gl.enableVertexAttribArray(vertexPositionAttribute);
// Draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
window.addEventListener('load', main);
์ด ์์๋ ์ ์ฒด ํ์ดํ๋ผ์ธ์ ๋ณด์ฌ์ค๋๋ค: ์ ฐ์ด๋ ์์ฑ, ์์ค ์ ๊ณต, ๊ฐ ์ ฐ์ด๋ ์ปดํ์ผ, ํ๋ก๊ทธ๋จ ์์ฑ, ์ ฐ์ด๋ ์ฒจ๋ถ, ํ๋ก๊ทธ๋จ ๋งํน, ๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋๋งํ๋ ๊ณผ์ ์ ๋๋ค. ์ค๋ฅ ํ์ธ ํจ์๋ ๊ฒฌ๊ณ ํ ๊ฐ๋ฐ์ ํ์์ ์ ๋๋ค.
์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ๋ฌธ์ ํด๊ฒฐ
์๋ จ๋ ๊ฐ๋ฐ์์กฐ์ฐจ ์ ฐ์ด๋ ๊ฐ๋ฐ ์ค์ ๋ฌธ์ ์ ์ง๋ฉดํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ ํจ์ ์ ์ดํดํ๋ฉด ๋๋ฒ๊น ์๊ฐ์ ํฌ๊ฒ ์ ์ฝํ ์ ์์ต๋๋ค:
- GLSL ๊ตฌ๋ฌธ ์ค๋ฅ: ๊ฐ์ฅ ๋น๋ฒํ ๋ฌธ์ ์
๋๋ค. ํญ์
gl.getShaderInfoLog()์์ `unexpected token`, `syntax error` ๋๋ `undeclared identifier`์ ๊ฐ์ ๋ฉ์์ง๋ฅผ ํ์ธํ์ญ์์ค. - ์ ํ ๋ถ์ผ์น: GLSL ๋ณ์ ์ ํ(
vec4,float,mat4)์ด ์ ๋ํผ์ ์ค์ ํ๊ฑฐ๋ ์์ฑ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์ฌ์ฉ๋๋ JavaScript ์ ํ๊ณผ ์ผ์นํ๋์ง ํ์ธํ์ญ์์ค. ์๋ฅผ ๋ค์ด, ๋จ์ผ `float`๋ฅผ `vec3` ์ ๋ํผ์ ์ ๋ฌํ๋ ๊ฒ์ ์ค๋ฅ์ ๋๋ค. - ์ ์ธ๋์ง ์์ ๋ณ์: GLSL์์
uniform๋๋attribute๋ฅผ ์ ์ธํ๋ ๊ฒ์ ์๊ฑฐ๋ ์คํ๊ฐ ์์ผ๋ฉด ์ปดํ์ผ ๋๋ ๋งํน ์ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. - ๋ถ์ผ์นํ๋ ๋ฒ ๋ฆฌ์(Varyings, WebGL 1.0) /
out/in(WebGL 2.0): ๋ฒํ ์ค ์ ฐ์ด๋์varying/out๋ณ์์ ์ด๋ฆ, ์ ํ ๋ฐ ์ ๋ฐ๋๋ ๋งํน์ด ์ฑ๊ณตํ๋ ค๋ฉด ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ํด๋นvarying/in๋ณ์์ ์ ํํ ์ผ์นํด์ผ ํฉ๋๋ค. - ์๋ชป๋ ์์ฑ/์ ๋ํผ ์์น: ์์ฑ/์ ๋ํผ ์์น๋ฅผ ์ฟผ๋ฆฌํ๋ ๊ฒ์ ์๊ฑฐ๋(
gl.getAttribLocation(),gl.getUniformLocation()) ์ ฐ์ด๋๋ฅผ ์์ ํ ํ ์ค๋๋ ์์น๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๋๋ง ๋ฌธ์ ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. - ์์ฑ ํ์ฑํ ๋๋ฝ: ์ฌ์ฉ ์ค์ธ ์์ฑ์ ๋ํด
gl.enableVertexAttribArray()๋ฅผ ์์ผ๋ฉด ์ ์๋์ง ์์ ๋์์ด ๋ฐ์ํฉ๋๋ค. - ์ค๋๋ ์ปจํ
์คํธ: ํญ์ ์ฌ๋ฐ๋ฅธ
gl์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ์ ํจํ์ง ํ์ธํ์ญ์์ค. - ๋ฆฌ์์ค ์ ํ: GPU๋ ์์ฑ, ๋ฒ ๋ฆฌ์ ๋๋ ํ ์ค์ฒ ์ ๋ ์์ ์ ํ์ด ์์ต๋๋ค. ๋ณต์กํ ์ ฐ์ด๋๋ ๊ตฌํ ๋๋ ์ฑ๋ฅ์ด ๋ฎ์ ํ๋์จ์ด์์ ์ด๋ฌํ ์ ํ์ ์ด๊ณผํ์ฌ ๋งํน ์คํจ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- ๋๋ผ์ด๋ฒ๋ณ ๋์: WebGL์ด ํ์คํ๋์ด ์์ง๋ง, ์ฌ์ํ ๋๋ผ์ด๋ฒ ์ฐจ์ด๋ก ์ธํด ๋ฏธ๋ฌํ ์๊ฐ์ ๋ถ์ผ์น ๋๋ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ค์ํ ๋ธ๋ผ์ฐ์ ๋ฐ ์ฅ์น์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ ์คํธํ์ญ์์ค.
์น ๊ทธ๋ํฝ์ค ์ ฐ์ด๋ ์ปดํ์ผ์ ๋ฏธ๋
WebGL์ด ๊ฐ๋ ฅํ๊ณ ๋๋ฆฌ ์ฑํ๋ ํ์ค์ผ๋ก ๋จ์ ์์ง๋ง, ์น ๊ทธ๋ํฝ์ค ํ๊ฒฝ์ ํญ์ ์งํํ๊ณ ์์ต๋๋ค. WebGPU์ ๋ฑ์ฅ์ Vulkan, Metal, DirectX 12์ ๊ฐ์ ๋ค์ดํฐ๋ธ ๊ทธ๋ํฝ์ค API๋ฅผ ๋ฐ์ํ๋ ๋ณด๋ค ํ๋์ ์ด๊ณ ์ ์์ค์ API๋ฅผ ์ ๊ณตํ๋ฉฐ ์๋นํ ๋ณํ๋ฅผ ์๋ฏธํฉ๋๋ค. WebGPU๋ ์ ฐ์ด๋ ์ปดํ์ผ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์น๋ ์ฌ๋ฌ ๋ฐ์ ์ ๋์ ํฉ๋๋ค:
- SPIR-V ์ ฐ์ด๋: WebGPU๋ ์ฃผ๋ก ์ ฐ์ด๋๋ฅผ ์ํ ์ค๊ฐ ๋ฐ์ด๋๋ฆฌ ํ์์ธ SPIR-V(Standard Portable Intermediate Representation - V)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฐ๋ฐ์๊ฐ ์ ฐ์ด๋(WGSL โ WebGPU ์ ฐ์ด๋ฉ ์ธ์ด, ๋๋ GLSL, HLSL, MSL๊ณผ ๊ฐ์ ๋ค๋ฅธ ์ธ์ด๋ก ์์ฑ๋จ)๋ฅผ ์คํ๋ผ์ธ์์ SPIR-V๋ก ์ปดํ์ผํ ๋ค์, ์ด ๋ฏธ๋ฆฌ ์ปดํ์ผ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ GPU์ ์ง์ ์ ๊ณตํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์ด๋ ๋ฐํ์ ์ปดํ์ผ ์ค๋ฒํค๋๋ฅผ ํฌ๊ฒ ์ค์ด๊ณ ๋ณด๋ค ๊ฐ๋ ฅํ ์คํ๋ผ์ธ ๋๊ตฌ ๋ฐ ์ต์ ํ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๋ช ์์ ํ์ดํ๋ผ์ธ ๊ฐ์ฒด: WebGPU ํ์ดํ๋ผ์ธ์ ๋์ฑ ๋ช ์์ ์ด๊ณ ๋ถ๋ณ์ ์ ๋๋ค. ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ๋จ๊ณ, ํด๋น ์ง์ ์ , ๋ฒํผ ๋ ์ด์์ ๋ฐ ๊ธฐํ ์ํ๋ฅผ ํฌํจํ๋ ๋ ๋ ํ์ดํ๋ผ์ธ์ ํ ๋ฒ์ ๋ชจ๋ ์ ์ํฉ๋๋ค.
WebGPU์ ์๋ก์ด ํจ๋ฌ๋ค์์๋ ๋ถ๊ตฌํ๊ณ , ๋ค๋จ๊ณ ์ ฐ์ด๋ ์ฒ๋ฆฌ์ ๊ธฐ๋ณธ ์๋ฆฌ๋ฅผ ์ดํดํ๋ ๊ฒ์ ์ฌ์ ํ ์ค์ํฉ๋๋ค. ๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ์ฒ๋ฆฌ, ์ ๋ ฅ ๋ฐ ์ถ๋ ฅ ๋งํน, ๊ทธ๋ฆฌ๊ณ ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ์ ํ์์ฑ์ ๋ชจ๋ ํ๋ ๊ทธ๋ํฝ์ค API์ ๊ทผ๋ณธ์ ๋๋ค. WebGL ํ์ดํ๋ผ์ธ์ ์ด๋ฌํ ๋ณดํธ์ ์ธ ๊ฐ๋ ์ ์ดํดํ๋ ๋ฐ ํ๋ฅญํ ๊ธฐ๋ฐ์ ์ ๊ณตํ์ฌ ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์๋ฅผ ์ํ ๋ฏธ๋ API๋ก์ ์ ํ์ ๋ ์ํํ๊ฒ ๋ง๋ญ๋๋ค.
๊ฒฐ๋ก : WebGL ์ ฐ์ด๋์ ์์ ๋ง์คํฐํ๊ธฐ
๋ฒํ ์ค ๋ฐ ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋์ ๋ค๋จ๊ณ ์ฒ๋ฆฌ๋ฅผ ํฌํจํ๋ WebGL ์ ฐ์ด๋ ์ปดํ์ผ ํ์ดํ๋ผ์ธ์ ์น์์ ์ค์๊ฐ 3D ๊ทธ๋ํฝ์ ์ํ ์ต๋ ์ฑ๋ฅ๊ณผ ์ ์ฐ์ฑ์ ์ ๊ณตํ๋๋ก ์ค๊ณ๋ ์ ๊ตํ ์์คํ ์ ๋๋ค. GLSL ์์ค ์ฝ๋์ ์ด๊ธฐ ์ ๊ณต๋ถํฐ ์คํ ๊ฐ๋ฅํ GPU ํ๋ก๊ทธ๋จ์ผ๋ก์ ์ต์ข ๋งํน์ ์ด๋ฅด๊ธฐ๊น์ง ๊ฐ ๋จ๊ณ๋ ์ถ์์ ์ธ ์ํ์ ๋ช ๋ น์ ์ฐ๋ฆฌ๊ฐ ๋งค์ผ ์ฆ๊ธฐ๋ ๋ฉ์ง ์๊ฐ์ ๊ฒฝํ์ผ๋ก ๋ณํํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
์ด ํ์ดํ๋ผ์ธ(๊ด๋ จ ํจ์, ๊ฐ ๋จ๊ณ์ ๋ชฉ์ , ์ค๋ฅ ํ์ธ์ ์ค์์ฑ ํฌํจ)์ ์ฒ ์ ํ ์ดํดํจ์ผ๋ก์จ ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ ๋ณด๋ค ๊ฒฌ๊ณ ํ๊ณ ํจ์จ์ ์ด๋ฉฐ ๋๋ฒ๊น ๊ฐ๋ฅํ WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ฅผ ๊ฒฉ๋ฆฌํ๊ณ , ๋ชจ๋์ฑ์ ํ์ฉํ๋ฉฐ, ๋ค์ํ ํ๋์จ์ด ํ๊ฒฝ์ ์ต์ ํํ๋ ๋ฅ๋ ฅ์ ๋ํํ ์น ์ฝํ ์ธ ์์ ๊ฐ๋ฅํ ๊ฒ์ ๊ฒฝ๊ณ๋ฅผ ๋ํ ์ ์๋๋ก ํด์ค๋๋ค. WebGL ์ฌ์ ์ ๊ณ์ํ๋ฉด์ ์ ฐ์ด๋ ์ปดํ์ผ ํ๋ก์ธ์ค๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ ๋จ์ํ ๊ธฐ์ ์ ์๋ จ๋์ ๊ดํ ๊ฒ์ด ์๋์ ๊ธฐ์ตํ์ญ์์ค. ์ง์ ์ผ๋ก ๋ชฐ์ ์ ์ด๊ณ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ๋์งํธ ์ธ๊ณ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ฐฝ์์ ์ ์ฌ๋ ฅ์ ์ฌ๋ ๊ฒ์ ๋๋ค.